home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / internet / sweeper / samples / olecon~1 / framewrk / internet.cpp < prev    next >
C/C++ Source or Header  |  1995-12-05  |  9KB  |  465 lines

  1. #include "IPServer.H"
  2. #include "Internet.H"
  3. #include "Util.H"
  4.  
  5.  
  6. static VARTYPE rgI4[] = { VT_I4 }; 
  7.  
  8. typedef enum {
  9.     InternetEvent_Progress = 0,
  10.     InternetEvent_ReadyStateChange = 1
  11. } INTERNETEVENTS;
  12.  
  13. static EVENTINFO rgEvents [] = {
  14.     { DISPID_PROGRESS, 1, rgI4 },            // (long percentDone)
  15.     { DISPID_READYSTATECHANGE, 1, rgI4 },    // (OLE_READYSTATE newState)
  16. };
  17.  
  18.  
  19. // local class for doing async monitoring. It's not really all that
  20. // general purpose, but it does the job...
  21.  
  22.  
  23. class CDownloadSink : public IBindStatusCallback
  24. {
  25. public:
  26.     CDownloadSink(IUnknown *punkOuter,CInternetControl *,DISPID );
  27.     ~CDownloadSink();
  28.  
  29.     STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
  30.     STDMETHOD_(ULONG, AddRef)();
  31.     STDMETHOD_(ULONG, Release)();
  32.  
  33.     STDMETHOD(GetBindInfo)( 
  34.          DWORD * grfBINDF,
  35.          BINDINFO *pbindinfo);
  36.     
  37.     STDMETHOD(OnStartBinding)( 
  38.          IBinding *pib);
  39.     
  40.     STDMETHOD(GetPriority)( 
  41.          LONG *pnPriority);
  42.     
  43.     STDMETHOD(OnProgress)( 
  44.          ULONG ulProgress,
  45.          ULONG ulProgressMax,
  46.          ULONG ulStatusCode,
  47.          LPCWSTR pwzStatusText);
  48.     
  49.     STDMETHOD(OnDataAvailable )( 
  50.         DWORD grfBSCF,
  51.         DWORD dwSize,
  52.         FORMATETC *pfmtetc,
  53.         REFIID riid,
  54.         IUnknown *punk);
  55.         
  56.      STDMETHOD(OnLowResource)( 
  57.          DWORD reserved);
  58.     
  59.     STDMETHOD(OnStopBinding)( 
  60.          HRESULT hrError);
  61.  
  62.     CDownloadSink * Next()                    { return(m_next); }
  63.     void            Next(CDownloadSink *n)  { m_next = n; }
  64.  
  65.     DISPID            DispId()  { return(m_propId); }
  66.     IBinding *        Binding() { return(m_binding); }
  67.  
  68. private:
  69.  
  70.     CDownloadSink *        m_next;
  71.     CInternetControl *    m_control;
  72.     DISPID                m_propId;
  73.     IBinding *            m_binding;
  74.     DWORD                m_ref;
  75.  
  76. };
  77.  
  78.  
  79. CDownloadSink::CDownloadSink
  80. (
  81.     IUnknown *            punkOuter,
  82.     CInternetControl *    control, 
  83.     DISPID                propId
  84. )
  85. {
  86. //    CHECK_POINTER(control);
  87.  
  88.     m_control = control;
  89.     m_control->AddRef();
  90.  
  91.     m_propId  = propId;
  92.     m_next    = 0;
  93.     m_binding = 0;
  94.     m_ref     = 0;
  95. }
  96.  
  97. CDownloadSink::~CDownloadSink()
  98. {
  99.     if( m_control )
  100.         m_control->Release();
  101.     if( m_binding )
  102.         m_binding->Release();
  103. }
  104.  
  105. STDMETHODIMP
  106. CDownloadSink::QueryInterface(const GUID &iid,void **ppv )
  107.     if( IsEqualGUID(iid,IID_IUnknown) || IsEqualGUID(iid,IID_IBindStatusCallback) )
  108.     {
  109.         *ppv = this;
  110.         AddRef();
  111.         return(NOERROR);
  112.     }
  113.     return( E_NOINTERFACE );
  114. }
  115.  
  116. STDMETHODIMP_(ULONG)
  117. CDownloadSink::AddRef()
  118. {
  119.     return(++m_ref);
  120. }
  121.  
  122. STDMETHODIMP_(ULONG)
  123. CDownloadSink::Release()
  124. {
  125.     if(!--m_ref)
  126.     {
  127.         delete this;
  128.         return(0);
  129.     }
  130.     return( m_ref );
  131. }
  132.     
  133.  
  134. STDMETHODIMP 
  135. CDownloadSink::GetBindInfo( DWORD *grfBINDF, BINDINFO *pbindInfo)
  136. {
  137.     *grfBINDF = BINDF_ASYNCHRONOUS;
  138.     pbindInfo->szExtraInfo = 0;
  139.     return(NOERROR);
  140. }
  141.  
  142.  
  143. STDMETHODIMP
  144. CDownloadSink::OnStartBinding(IBinding *pib) 
  145. {
  146.     m_binding = pib;
  147.     pib->AddRef();
  148.     return(NOERROR);
  149. }
  150.  
  151.  
  152. STDMETHODIMP 
  153. CDownloadSink::GetPriority( LONG *pnPriority) 
  154. {
  155.     return(E_NOTIMPL);
  156. }
  157.  
  158. STDMETHODIMP 
  159. CDownloadSink::OnProgress
  160.      ULONG ulProgress,
  161.      ULONG ulProgressMax,
  162.      ULONG ulStatusCode,
  163.      LPCWSTR pwzStatusText
  164. {
  165.     return(m_control->OnProgress(m_propId,ulProgress,
  166.                             ulProgressMax,ulStatusCode,pwzStatusText) );
  167. }
  168.  
  169. STDMETHODIMP 
  170. CDownloadSink::OnDataAvailable
  171.      DWORD            grfBSCF,
  172.      DWORD            dwSize,
  173.      FORMATETC *    pFmtetc,
  174.      REFIID            iid,
  175.      IUnknown *        punk
  176. {
  177.     return(m_control->OnData(m_propId,grfBSCF,(IStream *)punk, dwSize ));
  178. }
  179.  
  180. STDMETHODIMP 
  181. CDownloadSink::OnLowResource( DWORD reserved) 
  182. {
  183.     m_binding->Abort();
  184.     return(S_OK);
  185. }
  186.  
  187. STDMETHODIMP 
  188. CDownloadSink::OnStopBinding(HRESULT hrError) 
  189. {
  190.     m_binding->Release();
  191.     m_binding = 0;
  192.     m_control->Release();
  193.     m_control = 0;
  194.  
  195.     return(NOERROR);
  196. }
  197.  
  198.  
  199.  
  200. //------------------------------------------------------
  201. //
  202. // class CInternetControl
  203. //
  204. //
  205. CInternetControl::CInternetControl
  206. (
  207.     IUnknown *    pUnkOuter, 
  208.     int            iPrimaryDispatch, 
  209.     void *        pMainInterface
  210. )
  211.     : COleControl(pUnkOuter,iPrimaryDispatch,pMainInterface)
  212. {
  213.     m_downloads = 0;
  214.     m_host = 0;
  215.     m_readyState = READYSTATE_LOADING;
  216. }
  217.  
  218. CInternetControl::~CInternetControl()
  219. {
  220.     if( m_downloads )
  221.     {
  222.         CDownloadSink * next;
  223.         do 
  224.         {
  225.             next = m_downloads->Next();
  226.             IBinding * binding = m_downloads->Binding();
  227.             if( binding )
  228.                 binding->Abort();
  229.             m_downloads->Release();
  230.  
  231.         } while ( (m_downloads = next) != 0 );
  232.     }
  233.  
  234.     if( m_host )
  235.         m_host->Release();
  236. }
  237.  
  238.  
  239. HRESULT CInternetControl::InternalQueryInterface
  240. (
  241.     REFIID  riid,
  242.     void  **ppvObjOut
  243. )
  244. {
  245.     IUnknown *pUnk;
  246.  
  247.     *ppvObjOut = NULL;
  248.  
  249.     if (DO_GUIDS_MATCH(riid, IID_IServiceProvider)) {
  250.         pUnk = (IUnknown *)(IServiceProvider *)this;
  251.     } else{
  252.         return COleControl::InternalQueryInterface(riid, ppvObjOut);
  253.     }
  254.  
  255.     pUnk->AddRef();
  256.     *ppvObjOut = (void *)pUnk;
  257.     return S_OK;
  258. }
  259.  
  260. STDMETHODIMP 
  261. CInternetControl::QueryService(REFGUID guidService,
  262.             REFIID riid, void **ppvObject)
  263. {
  264.     HRESULT hr;
  265.  
  266.     IServiceProvider * clientsProvider;
  267.  
  268.     hr = m_pClientSite->QueryInterface(IID_IServiceProvider,
  269.                                             (void**)&clientsProvider );
  270.  
  271.     if( SUCCEEDED(hr) )
  272.     {
  273.         hr = clientsProvider->QueryService(guidService,
  274.                                     riid,ppvObject);
  275.         clientsProvider->Release();
  276.     }
  277.  
  278.     return(hr);
  279. }
  280.  
  281.  
  282. HRESULT 
  283. CInternetControl::GetBindHost(IBindHost ** pHost )
  284. {
  285.     HRESULT hr;
  286.     if( !m_host )
  287.         hr = GetBindHost();
  288.     else
  289.         hr = NOERROR;
  290.     *pHost = m_host;
  291.     return(hr);
  292. }
  293.  
  294. HRESULT 
  295. CInternetControl::GetBindHost()
  296. {
  297.     if( m_host )
  298.         return(NOERROR);
  299.  
  300.     IServiceProvider * serviceProvider = 0;
  301.  
  302.     HRESULT hr = m_pClientSite->QueryInterface
  303.                                     (
  304.                                         IID_IServiceProvider,
  305.                                         (void**)&serviceProvider
  306.                                     );
  307.  
  308.     if( SUCCEEDED(hr) )
  309.         hr = serviceProvider->QueryService( SID_BindHost, IID_IBindHost,
  310.                                             (void**)&m_host );
  311.     else
  312.         hr = E_FAIL; // C_E_UNKNOWNSERVICE;
  313.  
  314.     return(hr);
  315. }
  316.  
  317. HRESULT CInternetControl::GetAMoniker( LPOLESTR url, IMoniker ** ppmkr )
  318. {
  319.     HRESULT hr = GetBindHost();
  320.  
  321.     if( SUCCEEDED(hr) )
  322.         hr = m_host->ParseDisplayName(url,ppmkr);
  323.  
  324.     if( FAILED(hr) )
  325.        // FUTURE: This really should be a call to MkParseDisplayNameEx!!!
  326.         hr = ::CreateURLMoniker(0,url,ppmkr); 
  327.  
  328.     return( hr );
  329. }
  330.  
  331.  
  332. HRESULT CInternetControl::SetupDownload( IMoniker * moniker, DISPID propId )
  333. {
  334.     HRESULT hr = GetBindHost();
  335.  
  336.     IBindCtx * pBindCtx = 0;
  337.  
  338.     if( SUCCEEDED(hr) )
  339.         hr = m_host->GetBindCtx(0,&pBindCtx);
  340.  
  341.     if( FAILED(hr) )
  342.         hr = ::CreateBindCtx(0,&pBindCtx);
  343.  
  344.     CDownloadSink * sink = 0;
  345.  
  346.     if( SUCCEEDED(hr) )
  347.     {
  348.         sink = new CDownloadSink(0,this,propId);
  349.         if( sink )
  350.             sink->AddRef();
  351.     }
  352.  
  353.     if( SUCCEEDED(hr) && !sink )
  354.         hr = E_OUTOFMEMORY;
  355.     
  356.     if( SUCCEEDED(hr) )
  357.     {
  358.         // FUTURE: This should be a call to RegisterBindStatusCallback!!
  359.  
  360.         hr = pBindCtx->RegisterObjectParam(OLESTR("BindStatusCallback"), sink );
  361.     }
  362.         
  363.     IStream * strm = 0;
  364.  
  365.     if( SUCCEEDED(hr) )
  366.         hr = moniker->BindToStorage( pBindCtx, 0, IID_IStream, (void**)&strm );
  367.  
  368.     if( strm )
  369.         strm->Release();
  370.  
  371.     if( pBindCtx )
  372.         pBindCtx->Release();
  373.  
  374.     if( FAILED(hr) && sink )
  375.         sink->Release();
  376.  
  377.     if( SUCCEEDED(hr) )
  378.     {
  379.         if( m_downloads )
  380.             m_downloads->Next(sink);
  381.         m_downloads = sink;
  382.     }
  383.  
  384.     return(hr);
  385.  
  386. }
  387.  
  388. HRESULT CInternetControl::SetupDownload( LPOLESTR url, DISPID propId )
  389. {
  390.     CHECK_POINTER(url);
  391.  
  392.     IMoniker * pmkr;
  393.  
  394.     HRESULT hr = GetAMoniker( url, &pmkr );
  395.  
  396.     if( SUCCEEDED(hr) )
  397.         return( SetupDownload(pmkr,propId) );
  398.  
  399.     return(hr);
  400.  
  401. }
  402.  
  403. HRESULT CInternetControl::SetupDownload( IStream * propStream, DISPID propId )
  404. {
  405.     CHECK_POINTER(propStream);
  406.  
  407.     IMoniker * pmkr;
  408.  
  409.     HRESULT hr = ::OleLoadFromStream(propStream,IID_IMoniker,(void**)&pmkr);
  410.  
  411.     if( SUCCEEDED(hr) )
  412.         return( SetupDownload(pmkr,propId) );
  413.  
  414.     return(hr);
  415. }
  416.  
  417.  
  418. HRESULT CInternetControl::OnData( DISPID, DWORD,IStream *, DWORD)
  419. {
  420.     return(NOERROR);
  421. }
  422.  
  423. HRESULT CInternetControl::OnProgress( DISPID, ULONG progress, ULONG themax, ULONG, LPCWSTR)
  424. {
  425.     return(NOERROR);
  426. }
  427.  
  428. HRESULT CInternetControl::GetBinding(DISPID dispId,IBinding** ppBinding)
  429. {
  430.     CHECK_POINTER(ppBinding);
  431.  
  432.     CDownloadSink * sink = m_downloads;
  433.  
  434.     while(sink)
  435.     {
  436.         if( sink->DispId() == dispId )
  437.         {
  438.             if( (*ppBinding = sink->Binding()) == 0 )
  439.                 return( E_PENDING );
  440.             return(S_OK);
  441.         }
  442.         sink = sink->Next();
  443.     }
  444.  
  445.     return(E_FAIL);
  446. }
  447.  
  448.  
  449. HRESULT    CInternetControl::FireReadyStateChange( long newState )
  450. {
  451.     FireEvent( &::rgEvents[InternetEvent_ReadyStateChange], m_readyState = newState );
  452.     return(S_OK);
  453. }
  454.  
  455. HRESULT CInternetControl::FireProgress( ULONG dwAmount )
  456. {
  457.     FireEvent( &::rgEvents[InternetEvent_Progress], dwAmount );
  458.     return(S_OK);
  459. }
  460.